import type { Directive } from 'vue'

/** 定义一个持续执行时间的常量 */
const DURATION = 1500

/**
 * @description 数字动画指令
 */
export const numIncrease: Directive = {
  // 当指令绑定到元素上时调用
  mounted(el, binding) {
    // 获取指令的值
    const { value: maxCount } = binding

    // 调用animate函数，传入回调函数和持续时间
    el.$animate = animate((progress) => {
      // 将元素的文本设置为进度乘以最大值
      el.innerText = Math.floor(progress * maxCount)
    }, DURATION)
  },
  // 当指令从元素上解绑时调用
  unmounted(el) {
    // 取消动画
    el.$animate?.cancel()
  }
}
// 定义一个animate函数，用于创建动画
export function animate(
  callback: (progress: number) => void,
  duration: number
) {
  let animation: number, start: number, cancel: () => void
  // 定义一个anim函数，用于执行动画
  const anim = () => {
    // 获取当前时间
    const now = new Date().getTime()
    // 计算进度
    const progress = Math.floor(((now - start) / duration) * 100) / 100
    // 调用回调函数，传入进度
    callback(progress > 1 ? 1 : progress)
    // 如果进度超过1，则取消动画
    if (now - start > duration) {
      cancel()
    }
    // 定义一个cancel函数，用于取消动画
    cancel = () => {
      cancelAnimationFrame(animation)
    }
    // 获取当前时间
    start = new Date().getTime()
    // 请求下一帧动画
    animation = requestAnimationFrame(anim)
    // 返回一个对象，包含一个cancel函数，用于取消动画
    return {
      cancel: () => {
        cancelAnimationFrame(animation)
      }
    }
  }
  // 执行动画
  anim()
}
